package cn.hh.hrm.controller;



import cn.hh.hrm.config.HighlightResultMapper;
import cn.hh.hrm.doc.CourseDoc;
import cn.hh.hrm.query.CourseDocQuery;
import cn.hh.hrm.repository.CourseDocRepository;
import cn.hh.hrm.util.AjaxResult;
import cn.hh.hrm.vo.AggVo;
import cn.hh.hrm.vo.PageList;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/courseDoc")
public class CourseDocController {
    //注入CourseDocRepository
    @Autowired
    private CourseDocRepository courseDocRepository;
    @Autowired
    private HighlightResultMapper highlightResultMapper;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @PostMapping("/onLine")
    public AjaxResult onLineCourse(@RequestBody CourseDoc courseDoc){
        courseDocRepository.save(courseDoc);
        return  AjaxResult.me();
    }
    @PostMapping("/offLine")
    public AjaxResult offLineCourse(@RequestBody CourseDoc courseDoc){
        courseDocRepository.deleteById(courseDoc.getId());
        return  AjaxResult.me();
    }
    @PostMapping("/queryCourses")
    public AjaxResult queryCourses(@RequestBody CourseDocQuery docQuery){
        System.out.println("接收到的数据++++++++"+docQuery);
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //关键字查询
        String keyword = docQuery.getKeyword();
        if(StringUtils.isNotBlank(keyword)){
            //只支持一个字段
            //boolQueryBuilder.must(QueryBuilders.matchQuery("name", keyword));
            //多个字段
            boolQueryBuilder.must(QueryBuilders.multiMatchQuery(keyword,"name","tenantName","gradeName"));
        }
        //价格过滤
        Float priceMax = docQuery.getPriceMax();
        if(priceMax!=null){
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(priceMax));
        }
        Float priceMin= docQuery.getPriceMin();
        if(priceMin!=null){
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(priceMin));
        }
        builder.withQuery(boolQueryBuilder);

        //聚合关键词查询
        Long courseTypeId = docQuery.getCourseTypeId();
        if(courseTypeId!=null){
            boolQueryBuilder.filter(QueryBuilders.termQuery("courseTypeId", courseTypeId));
        }
        String tenantName = docQuery.getTenantName();
        if(StringUtils.isNotBlank(tenantName)){
            boolQueryBuilder.filter(QueryBuilders.termQuery("tenantName", tenantName));
        }
        //排序
        //获取排序字段  排序的类型
        String sortField = docQuery.getSortField();
        //  前端如果没有排序字段 默认使用价格排序
        sortField = (sortField == null || sortField.trim().equals(""))?"price":sortField;
        String sortType = docQuery.getSortType();
        SortOrder type = (sortType == null|| SortOrder.DESC.toString().equals(sortType)) ? SortOrder.DESC:SortOrder.ASC;
        //以哪个字段排序
        FieldSortBuilder sortBuilder = new FieldSortBuilder(sortField);
        //指定排序类型
        sortBuilder.order(type);
        builder.withSort(sortBuilder);
        //分页
        PageRequest pageRequest = PageRequest.of(docQuery.getPage()-1, docQuery.getRows());
        builder.withPageable(pageRequest);
        //高亮处理
        //设置高亮显示
        HighlightBuilder.Field field = new HighlightBuilder.Field("name").preTags("<font style='color:red'><b>").postTags("</b></font>");
        builder.withHighlightFields(field);  // 名字高亮
        //聚合
        //聚合查询,按照机构名字聚合，安装数量倒排
        builder.addAggregation(AggregationBuilders.terms("tenantNameAgg").field("tenantName").order(Terms.Order.count(false)).size(4));
        builder.addAggregation(AggregationBuilders.terms("courseTypeAgg").field("courseTypeName").order(Terms.Order.count(false)).size(4));
        //courseDocRepository 不支持高亮处理
        //Page<CourseDoc> docs = courseDocRepository.search(builder.build());
        AggregatedPage<CourseDoc> docs = elasticsearchTemplate.queryForPage(builder.build(), CourseDoc.class, highlightResultMapper);
        //聚合查询数据封装
        StringTerms tenantTerms = (StringTerms) docs.getAggregation("tenantNameAgg");
        //定义集合 封装机构聚合数据
        List<AggVo>  tenantList = new ArrayList<>();
        //获取getBuckets
        List<StringTerms.Bucket> tenantAgg = tenantTerms.getBuckets();
        tenantAgg.stream().forEach(bucket -> {
            AggVo aggVo = new AggVo();
            aggVo.setName(bucket.getKeyAsString());
            aggVo.setCount(bucket.getDocCount());
            tenantList.add(aggVo);
        });
        StringTerms courseTerms = (StringTerms) docs.getAggregation("courseTypeAgg");
        //定义集合 封装机构聚合数据
        List<AggVo>  courseList = new ArrayList<>();
        //获取getBuckets
        List<StringTerms.Bucket> courseAgg = courseTerms.getBuckets();
        courseAgg.stream().forEach(bucket -> {
            AggVo aggVo = new AggVo();
            aggVo.setName(bucket.getKeyAsString());
            aggVo.setCount(bucket.getDocCount());
            courseList.add(aggVo);
        });
        //创建map
        HashMap<String, List<AggVo>> map = new HashMap<>();
        map.put("tenantList", tenantList);
        map.put("courseList", courseList);

        return AjaxResult.me().setResultObj(new PageList<CourseDoc>(docs.getTotalElements(),docs.getContent(),map));
    }
}
